package com.jacobson.core.widget.security.mgt

import com.jacobson.core.widget.security.Subject
import com.jacobson.core.widget.security.SecurityManager
import com.jacobson.core.widget.security.authc.AuthenticationToken
import com.jacobson.core.widget.security.exception.AuthenticationException
import io.reactivex.Observable

/**
 * ================================================
 *
 *  @author Wucz on 2018/8/7 9:26
 * ================================================
 */
class DelegatingSubject(
        principal: Any?,
        authenticated: Boolean,
        securityManager: SecurityManager
) : Subject {
    override var principal: Any? = null
    override var remembered: Boolean = false
    override var authenticated: Boolean = false
    private var securityManager: SecurityManager? = null

    init {
        this.principal = principal
        this.authenticated = authenticated
        this.securityManager = securityManager
    }


    /**
     * 登录
     *
     * @param token 登录Token
     * @throws AuthenticationException 登录异常
     */
    override fun login(token: AuthenticationToken): Observable<Subject?> {
        return Observable.just(token)
                .map {
                    //返回的结果不为空，认为登录成功。否则登录失败
                    val subject = securityManager?.login(this, it)
                    subject?.principal?.let { principal ->
                        this.principal = principal
                        this.authenticated = true
                    } ?: run {
                        throw AuthenticationException("principal returned from securityManager.login(token) returned a null. This value must be non null!")
                    }
                    return@map subject
                }
    }

    /**
     * 退出登录
     */
    override fun logout() {
        try {
            this.securityManager?.logout(this)
        } finally {
            this.principal = null
            this.authenticated = false
        }
    }

}